package com.xhwl.logistics.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xhwl.common.dto.cent.vehicle.SupplierConfigDTO;
import com.xhwl.common.enums.CategoryEnum;
import com.xhwl.common.enums.vehicle.CardTypeEnum;
import com.xhwl.common.enums.vehicle.ParkSupplierEnum;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.device.DeviceProjSupplierCategory;
import com.xhwl.common.pojo.cent.sdata.Project;
import com.xhwl.common.pojo.cent.vehicle.VehcArea;
import com.xhwl.common.pojo.cent.vehicle.VehcCardChargeRule;
import com.xhwl.common.pojo.cent.vehicle.VehcParkingLot;
import com.xhwl.common.query.cent.device.ProductAccessQuery;
import com.xhwl.common.query.cent.sdata.ProjectQuery;
import com.xhwl.common.query.cent.vehicle.CardChargeRuleQuery;
import com.xhwl.common.query.cent.vehicle.CardQuery;
import com.xhwl.common.vo.cent.vehicle.CardChargeRuleVO;
import com.xhwl.logistics.dao.VehcAreaDao;
import com.xhwl.logistics.dao.VehcCardChargeRuleDao;
import com.xhwl.logistics.dao.VehcParkingLotDao;
import com.xhwl.logistics.dto.CardDTO;
import com.xhwl.logistics.service.IVehcCardChargeRuleService;
import com.xhwl.logistics.service.cent.IProductAccessCentService;
import com.xhwl.logistics.service.cent.IProjectService;
import com.xhwl.logistics.strategy.InfoSyncSupplierStrategy;
import com.xhwl.logistics.strategy.context.InfoSyncSupplierStrategyContext;
import com.xhwl.logistics.util.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Lu.Aaron
 * @since 2021-07-07
 */
//@Service
public class VehcCardChargeRuleServiceImpl extends ServiceImpl<VehcCardChargeRuleDao, VehcCardChargeRule> implements IVehcCardChargeRuleService {
    @Autowired
    private VehcCardChargeRuleDao vehcCardChargeRuleDao;
    @Autowired
    private VehcParkingLotDao vehcParkingLotDao;
    @Autowired
    private VehcAreaDao vehcAreaDao;
    @Autowired
    private IProjectService projectService;
    @Autowired
    private InfoSyncSupplierStrategyContext infoSyncSupplierStrategyContext;
    @Autowired
    private IProductAccessCentService productAccessCentService;

    @Override
    public ResultJson add(CardChargeRuleVO cardChargeRuleVO) {
        VehcCardChargeRule vehcCardChargeRule = new VehcCardChargeRule();
        BeanUtils.copyProperties(cardChargeRuleVO,vehcCardChargeRule);
        vehcCardChargeRuleDao.insert(vehcCardChargeRule);
        return ResultJson.success("新增成功");
    }

    @Override
    public ResultJson edit(CardChargeRuleVO cardChargeRuleVO) {
        Integer id = cardChargeRuleVO.getId();
        if (Objects.isNull(id)) {
            throw  new BusinessException("id必传");
        }
        VehcCardChargeRule vehcCardChargeRule = new VehcCardChargeRule();
        BeanUtils.copyProperties(cardChargeRuleVO,vehcCardChargeRule);
        vehcCardChargeRuleDao.updateById(vehcCardChargeRule);
        return ResultJson.success("编辑成功");
    }

    @Override
    public ResultJson delete(Integer id) {
        vehcCardChargeRuleDao.deleteById(id);
        return ResultJson.success("删除成功");
    }

    @Override
    public ResultJson cardChargeRulePage(CardChargeRuleQuery cardChargeRuleQuery) {
        Integer areaId = cardChargeRuleQuery.getAreaId();
        CardTypeEnum cardType = cardChargeRuleQuery.getCardType();
        String name = cardChargeRuleQuery.getName();
        Integer parkingLotId = cardChargeRuleQuery.getParkingLotId();
        List<Integer> projectIds = cardChargeRuleQuery.getProjectIds();
        if (null==projectIds||projectIds.isEmpty()) {
            throw new BusinessException("项目id必传");
        }
        QueryWrapper<VehcCardChargeRule> wrapper = new QueryWrapper<>();


        wrapper.in("project_id",projectIds);

        if (null!=areaId) {
            wrapper.eq("area_id",areaId);
        }
        if (null!=cardType) {
            wrapper.eq("card_type",cardType.getKey());
        }
        if (StringUtils.isNotBlank(name)) {
            wrapper.like("name",name);
        }
        if (null!=parkingLotId) {
            wrapper.eq("parking_lot_id",parkingLotId);
        }
        Page<VehcCardChargeRule> page = new Page<>();
        page.setSize(cardChargeRuleQuery.getPageSize());
        page.setCurrent(cardChargeRuleQuery.getCurrent());
        Page<VehcCardChargeRule> selectPage = vehcCardChargeRuleDao.selectPage(page, wrapper);
        List<VehcCardChargeRule> records = selectPage.getRecords();
        if (records.isEmpty()) {
            return ResultJson.success(selectPage);
        }
        Set<Integer> areaIds = records.stream().map(r -> r.getAreaId()).collect(Collectors.toSet());
        Set<Integer> parkingLotIds = records.stream().map(r -> r.getParkingLotId()).collect(Collectors.toSet());
        ProjectQuery projectQuery = new ProjectQuery();
        projectQuery.withIdList(projectIds);
        List<Project> projects = projectService.list(projectQuery, null);
        List<VehcArea> vehcAreas = vehcAreaDao.selectBatchIds(areaIds);
        List<VehcParkingLot> vehcParkingLots = vehcParkingLotDao.selectBatchIds(parkingLotIds);
        records.forEach(r->{
            projects.forEach(p->{
                if (p.getId().equals(r.getProjectId())) {
                    r.setProjectName(p.getName());
                }
            });
            vehcParkingLots.forEach(vp->{
                if (vp.getId().equals(r.getParkingLotId())) {
                    r.setParkingLotName(vp.getName());
                }
            });
            vehcAreas.forEach(va->{
                if (va.getId().equals(r.getAreaId())) {
                    r.setAreaName(va.getName());
                }
            });
        });
        return ResultJson.success(selectPage);
    }

    @Override
    public ResultJson list(CardChargeRuleQuery cardChargeRuleQuery) {
        QueryWrapper<VehcCardChargeRule> wrapper = new QueryWrapper<>();
        List<Integer> projectIds = cardChargeRuleQuery.getProjectIds();
        if (null==projectIds||projectIds.isEmpty()) {
            throw new BusinessException("项目id必传");
        }
        Integer parkingLotId = cardChargeRuleQuery.getParkingLotId();
        if (null==parkingLotId) {
            throw new BusinessException("请先选择车场");
        }
        wrapper.in("project_id",projectIds);
        wrapper.eq("parking_lot_id",parkingLotId);
        List<VehcCardChargeRule> list = vehcCardChargeRuleDao.selectList(wrapper);
        List<Map<String, Object>> maps = new ArrayList<>();
        Map<String, Object> hashMap = new HashMap<>();
        hashMap.put("id",0);
        hashMap.put("name","无");
        hashMap.put("cardType","NO");
        maps.add(hashMap);
        list.forEach(l->{
            Map<String, Object> map = new HashMap<>();
            map.put("name",l.getName());
            map.put("id",l.getId());
            map.put("cardType",l.getCardType());
            maps.add(map);
        });

        return ResultJson.success(maps);
    }

    @Override
    public ResultJson chargeWay(Short industryId, CardQuery cardQuery) {
        //先根据项目id和产品分类id查询供应商
        Integer projectId = cardQuery.getProjectId();
        Integer parkingLotId = cardQuery.getParkingLotId();
        CardTypeEnum type = cardQuery.getType();
        if (Objects.isNull(projectId)) {
            throw new BusinessException("项目id必传");
        }
        if (Objects.isNull(parkingLotId)) {
            throw new BusinessException("车场id必传");
        }
        List<DeviceProjSupplierCategory> deviceProjSupplierCategories = productAccessCentService.listProductAccess(industryId, new ProductAccessQuery(projectId, CategoryEnum.YARD_GATE.getId()));
        if (deviceProjSupplierCategories.isEmpty()) {
            throw new BusinessException("该项目未配置供应商，请先配置");
        }
        DeviceProjSupplierCategory productAccess = deviceProjSupplierCategories.get(0);
        JSONObject properties = productAccess.getProperties();
        //获取供应商配置信息
        SupplierConfigDTO supplierConfigDTO = JSON.toJavaObject(properties, SupplierConfigDTO.class);
        //根据supplierId以及策略模式选取对应的接口实现类
        Integer supplierId = productAccess.getSupplierId();

        //临时修改关于收费方式查询接口，当厂商（科拓）接口返回空或者异常，那么返回临时定义的收费方式（该修改是临时方案）
        ParkSupplierEnum parkSupplierEnum = ParkSupplierEnum.getParkSupplierEnum(supplierId);
        if (Objects.isNull(parkSupplierEnum)) {
            parkSupplierEnum = ParkSupplierEnum.JIELINK;
        }
        InfoSyncSupplierStrategy infoSyncSupplierService = infoSyncSupplierStrategyContext.getInfoSyncSupplierService(parkSupplierEnum);
        //临时修改关于收费方式查询接口，当厂商（科拓）接口返回空或者异常，那么返回临时定义的收费方式（该修改是临时方案）

        Map<String, Object> map = new HashMap<>();
        CardDTO cardDTO = new CardDTO();
        if (type.equals(CardTypeEnum.MONTH)) {
            //cardDTO.setCarType(2);
            map.put("carType",2);
        }else if(type.equals(CardTypeEnum.STORE)){
            //cardDTO.setCarType(3);
            map.put("carType",3);
        }else if(type.equals(CardTypeEnum.TEMPORARILY)){
            //cardDTO.setCarType(0);
            map.put("carType",0);
        }else if(type.equals(CardTypeEnum.FREE)){
            //cardDTO.setCarType(1);//产品自己定义说明：（供应商VIP卡对应平台的免费卡）
            map.put("carType",1);
        }
        //查询车场对应的第三方id
        VehcParkingLot vehcParkingLot = vehcParkingLotDao.selectById(parkingLotId);
        String thirdParkId = vehcParkingLot.getThirdParkId();
        //cardDTO.setParkId(thirdParkId);
        map.put("parkId",thirdParkId);

        //临时修改关于收费方式查询接口，当厂商（科拓）接口返回空或者异常，那么返回临时定义的收费方式（该修改是临时方案）
        List<Map> maps;
        try {
            maps = infoSyncSupplierService.queryChargeWay(map, supplierConfigDTO);
        } catch (Exception e) {
            maps = new ArrayList<>();
        }
        if (maps.isEmpty()) {
            Map<String, Object> temporary = new HashMap<>();
            switch (type) {
                case FREE:
                    temporary.put("id", 1);
                    temporary.put("ruleName", "免收费");
                    temporary.put("amount", 0);
                    break;
                case MONTH:
                    temporary.put("id", 1);
                    temporary.put("ruleName", "月收费");
                    temporary.put("amount", 100);
                    break;
                case STORE:
                    temporary.put("id", 1);
                    temporary.put("ruleName", "充值套餐A");
                    temporary.put("amount", 50);
                    break;
                case TEMPORARILY:
                    temporary.put("id", 1);
                    temporary.put("ruleName", "临时收费");
                    temporary.put("amount", 5);
                    break;
                default:
                    throw new BusinessException("非法的车类类型参数");
            }
            maps.add(temporary);
        }
        //临时修改关于收费方式查询接口，当厂商（科拓）接口返回空或者异常，那么返回临时定义的收费方式（该修改是临时方案）
        return ResultJson.success(maps);
    }

    @Override
    public ResultJson feeServiceList(CardChargeRuleQuery cardChargeRuleQuery) {
        Integer parkingLotId = cardChargeRuleQuery.getParkingLotId();
        CardTypeEnum cardType = cardChargeRuleQuery.getCardType();
        if (null==parkingLotId) {
            throw new BusinessException("车场id必传");
        }
        if (null==cardType) {
            throw new BusinessException("卡类型必传");
        }
        QueryWrapper<VehcCardChargeRule> wrapper = new QueryWrapper<>();
        wrapper.eq("parking_lot_id",parkingLotId);
        wrapper.eq("card_type",cardType);
        List<VehcCardChargeRule> vehcCardChargeRules = vehcCardChargeRuleDao.selectList(wrapper);
        return ResultJson.success(vehcCardChargeRules);
    }
}
